package com.skiving.cloud.admin.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.mybatisflex.core.query.QueryWrapper;
import com.skiving.cloud.admin.entity.SysUser;
import com.skiving.cloud.admin.parameter.LoginParameter;
import com.skiving.cloud.admin.service.SysCaptchaService;
import com.skiving.cloud.admin.service.SysUserService;
import com.skiving.cloud.admin.vo.AdminRouteVue;
import com.skiving.cloud.auth.constant.AuthConstant;
import com.skiving.cloud.auth.entity.AuthUser;
import com.skiving.cloud.auth.util.UserUtil;
import com.skiving.cloud.common.utils.ReturnT;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.Utils;
import org.noear.solon.annotation.*;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.util.MimeType;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.util.List;

@Slf4j
@Controller
@Api("用户认证接口")
@Mapping("/auth")
@Produces(MimeType.APPLICATION_JSON_UTF8_VALUE)
public class LoginController {
    @Inject
    private SysCaptchaService sysCaptchaService;
    @Inject
    private SysUserService sysUserService;
    /**
     * 获取验证码
     * @param uuid 生成验证码的uuid
     * @throws Exception 异常
     */
    @ApiOperation("获取验证码图片")
    @Get
    @Mapping("/captcha.jpg")
    public void captcha(Context ctx, @Param(name="uuid") String uuid) throws Exception {
        //获取图片验证码
        BufferedImage image = sysCaptchaService.getCaptcha(uuid);
        // 禁止图像缓存
        ctx.headerSet("Pragma", "no-cache");
        ctx.headerSet("Cache-Control", "no-cache");
        ctx.headerSet("Expires", "0");
        ctx.contentType("image/png");
        ImageIO.setUseCache(false);
        ImageIO.write(image, "png", ctx.outputStream());
    }

    /**
     * 登录验证
     * */
    @ApiOperation("登录认证")
    @Post
    @Mapping("/login")
    public ReturnT<Boolean> login(@Body @ApiParam("认证参数") LoginParameter parameter, Context ctx) {

        //空内容检查
        if (Utils.isEmpty(parameter.getCaptcha())) {
            return ReturnT.error("提示：请输入验证码！");
        }

        if (Utils.isEmpty(parameter.getUsername()) || Utils.isEmpty(parameter.getPassword())) {
            return ReturnT.error("提示：请输入账号和密码！");
        }
        boolean validateCaptcha = sysCaptchaService.validate(parameter.getUuid(), parameter.getCaptcha());
        if(!validateCaptcha){
            return ReturnT.error("验证码不正确");
        }
        SysUser user = sysUserService.getOne(QueryWrapper.create().where(SysUser::getUsername).eq(parameter.getUsername()));
        boolean success = BCrypt.checkpw(parameter.getPassword(), user.getPassword());
        if (success) {
            //登录然后把用户信息存入session中
            StpUtil.login(user.getId());
            AuthUser sessionUser = new AuthUser();
            BeanUtil.copyProperties(user, sessionUser, true);
            StpUtil.getSession().set(AuthConstant.USER_SESSION, sessionUser);
            return ReturnT.ok(true);
        }else{
            return ReturnT.error("用户名或密码不正确", false);
        }
    }

    /**
     * 登出方法
     * @return 结果
     */
    @ApiOperation("用户登出")
    @Post
    @Mapping("/logout")
    public ReturnT<String> logout(){
        StpUtil.logout();
        return ReturnT.ok("注销成功");
    }

    /**
     * 加载当前登陆用户的信息
     * @return 当前用户的信息
     */
    @ApiOperation("加载当前登陆用户的信息")
    @Get
    @Mapping("/getUserInfoSession")
    public ReturnT<AuthUser> getUserInfoSession(){
        //当前登陆用户
        AuthUser user = UserUtil.getCurrentUser();
        return ReturnT.ok(user);
    }

    /**
     * 加载当前登陆用户的菜单
     * @param terminal 终端 Constant.TerminalType
     * @return 当前用户的菜单
     */
    @ApiOperation("加载当前登陆用户的菜单")
    @Get
    @Mapping("/getAllMenuForUserVue/{terminal}")
    public ReturnT<List<AdminRouteVue>> getAllMenuForUserVue(@Path("terminal") String terminal){
        //当前登陆用户
        AuthUser user = UserUtil.getCurrentUser();
        List<AdminRouteVue> routes = sysUserService.getAllMenuForUserVue(user.getId(), terminal);
        return ReturnT.ok(routes);
    }
}
